/******************************************************************************/
/*  Class FMEM_LAYER                                                          */
/*  PO: S. Maslyakov, rusoil.9@gmail.com                                      */
/*                                                                            */
/*  Revision:     1.2                                                         */
/*  Date:         2011/02/14 18:06:33                                         */
/******************************************************************************/


#ifndef __FMEM_LAYER_H
#define __FMEM_LAYER_H


#include "data_types.h"
#include "At25df\at25df.h"
#include "Fmem_layer\fmem_map.h"
#include "Fmem_layer\fmem_layer_def.h"


//==============================================================================
//  Class FMEM_LAYER
//==============================================================================
class FMEM_LAYER : public AT25DF
{

public:
  FMEM_LAYER(const uint32_t _saddr, const uint32_t _memSize)
             : m_fmemPageSize(FMEM_PAGE_SIZE), m_fmemSectorSize(FMEM_SECTOR_SIZE),
               m_fmemStartAddr(_saddr), m_fmemAllocatedSize(_memSize),
               m_isMemAlloc(FMEM_ALLOC_FLAG) {}

  FMEM_LAYER() : m_fmemPageSize(FMEM_PAGE_SIZE), m_fmemSectorSize(FMEM_SECTOR_SIZE),
                 m_fmemStartAddr(0), m_fmemAllocatedSize(0),
                 m_isMemAlloc(0) {}

  uint32_t WriteData(const __FMEM_DATA * const _pData);
  uint32_t ChangeData(const __FMEM_DATA * const _pData);
  uint32_t ReadData(const __FMEM_DATA * const _pData);
  uint32_t EraseMemory();

  inline uint32_t GetMemorySize() const { return m_fmemAllocatedSize; }
  inline uint32_t GetSectorSize() const { return m_fmemSectorSize; }
  inline uint32_t GetSpaceToEnd(const uint32_t _addr) const {
      return (_addr < m_fmemAllocatedSize) ? (m_fmemAllocatedSize - _addr) : 0;
  }

protected:
  void AllocMem(const uint32_t _saddr, const uint32_t _memSize) {
      if (m_isMemAlloc != FMEM_ALLOC_FLAG) {
          m_fmemStartAddr = _saddr;
          m_fmemAllocatedSize = _memSize;
          m_isMemAlloc = FMEM_ALLOC_FLAG;
      };
  }

  inline uint32_t ConvertExtAddrInHwAddr(const uint32_t _extAddr) const {
      return (m_fmemStartAddr + _extAddr);
  }

  inline uint32_t GetWriteDataLen(const uint32_t _addr) const {
      return ((((_addr / m_fmemPageSize) + 1) * m_fmemPageSize) - _addr);
  }

  inline bool_t TestAddrRange(const uint32_t _addr) const {
      return (_addr < m_fmemAllocatedSize) ? TRUE_T : FALSE_T;
  }

  inline bool_t TestNewSectorWrite(const uint32_t _addr) const {
      return (_addr % m_fmemSectorSize) ? FALSE_T : TRUE_T;
  }

private:
  const uint32_t m_fmemPageSize;
  const uint32_t m_fmemSectorSize;
  uint32_t m_fmemStartAddr;
  uint32_t m_fmemAllocatedSize;
  uint32_t m_isMemAlloc;
};
//==============================================================================
//==============================================================================


#endif